/**
 * @file dot_writer.c
 * @brief Functions for printing a module to a dot file
 * @author Scott Moyers
 * @date 2008
 */

#include "dot_writer.h"
#include <assert.h>

static void print_header_dot(FILE *fp);
static void print_footer_dot(FILE *fp);

void print_module_dot(FILE *fp, struct Module *m, enum DotSwitches sw)
{
	unsigned int i;
	print_header_dot(fp);

	for(i = 0; i < m->num_inputs; i++) {
		fprintf(fp, "\t%d [label=i%d] [shape=point]\n", i, i);
		fprintf(fp, "\tinsig%d [shape=point]\n", i);
		fprintf(fp, "\t%d -> insig%d", i, i);
		if ((sw & SIGNALS) != 0) {
			fprintf(fp, " [label=\"");
			fprint_signal(fp, m->signals[i], signal_width(m->num_inputs));
			fprintf(fp, "\"]");
		}
		fprintf(fp, " [arrowhead=none] [style=dotted]\n");
	}

	for(i = 0; i < m->num_gates; i++) {
		struct Gate *g = &m->circuit[i];
		fprintf(fp, "\t%d [label=%s]\n", g->out, get_gate_name(g));
		if (num_gate_inputs(g) > 0) {
			fprintf(fp, "\t%d -> %d\n", g->in[0], g->out);
			if (num_gate_inputs(g) > 1) {
				fprintf(fp, "\t%d -> %d\n", g->in[1], g->out);
			}
		}

		fprintf(fp, "\to%d [shape=point]\n", g->out);
		fprintf(fp, "\t%d -> o%d", g->out, g->out);
		if ((sw & SIGNALS) != 0) {
			fprintf(fp, " [label=\"");
			fprint_signal(fp, m->signals[g->out], signal_width(m->num_inputs));
			fprintf(fp, "\"]");
		}
		fprintf(fp, " [arrowhead=none] [style=dotted]\n");
	}
	print_footer_dot(fp);
}

void print_header_dot(FILE * fp)
{
	fprintf(fp, "digraph module {\n");
	fprintf(fp, "\trankdir=LR\n");
}

void print_footer_dot(FILE * fp)
{
	fprintf(fp, "}\n");
}
